package cn.sisyphe.framework.ddd.events;



import cn.sisyphe.framework.ddd.annotations.DomainEvent;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * domain event
 * 领域事件基类
 * @author linux_china
 */
@DomainEvent
public class BaseDomainEvent<T> implements Serializable {

    private static final long serialVersionUID = 5516075349620653482L;
    /**
     * ID
     */
    private String id = UUID.randomUUID().toString();
    /**
     * event type
     */
    protected String type;
    /**
     * event context
     */
    protected Map<String, Object> context;
    /**
     * source
     */
    protected T source;
    /**
     * payload
     */
    protected Object payload;
    /**
     * System time when the event happened
     */
    private final long timestamp;


    public BaseDomainEvent() {
        this.timestamp = System.currentTimeMillis();
    }

    public BaseDomainEvent(T source) {
        this.source = source;
        this.timestamp = System.currentTimeMillis();
    }

    public BaseDomainEvent(T source, Object payload) {
        this.source = source;
        this.payload = payload;
        this.timestamp = System.currentTimeMillis();
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Object getSource() {
        return source;
    }

    public void setSource(T source) {
        this.source = source;
    }

    public Object getPayload() {
        return payload;
    }

    public void setPayload(T payload) {
        this.payload = payload;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public Object getAttribute(String name) {
        return context == null ? null : context.get(name);
    }

    public void setAttribute(String name, Object value) {
        if (context == null) {
            context = new HashMap<String, Object>(16);
        }
        this.context.put(name, value);
    }

    public Map<String, Object> getContext() {
        return context;
    }

    public void setContext(Map<String, Object> context) {
        this.context = context;
    }

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }


    @Override
    public String toString() {
        return "BaseDomainEvent{" +
                "id='" + id + '\'' +
                ", type='" + type + '\'' +
                ", context=" + context +
                ", source=" + source +
                ", payload=" + payload +
                ", timestamp=" + timestamp +
                '}';
    }
}
